#include <iostream>
#include "Vector.h"
#include <sys/time.h>
#include <cstdlib>

#define TESTNUM 25
#define TIMES 200
#define N 10000000

/**
* @brief To calculate the average number of the array.
* 
* @param num, size
*/
int average(const int* num, const int size)
{
    int ave = 0;
    for (int i = 0; i < size; i++)
    {
    ave += num[i];
    }
    ave /= size;
    return ave;
}

/**
* @brief To get the position of the minimal number.
* 
* @param num, size
*/
int minimal(const int* num, const int size)
{
    int ret = 0;
    for (int i = 1; i < size; i++)
    {
    if(num[ret] > num[i])
        ret = i;
    }
    return ret;
}

/**
* @brief To calculate the power number of the given number.
* 
* @param a, n
*/
int pow(int a, int n)
{
    int result = 1;
    for (int i = 0; i < n; i++)
        result *= a;
    return result;
}

/**
* @brief To test which SPARE_CAPACITY can be most effecient.
* 
*/
int main(int argc, char* argv[])
{

    Vector<int> a;
    for (int i = 0; i < N; i++)
    a.push_back(rand() % 7);
    if (a.empty())
    {
    std::cout << "Unable to expand the vector." << std::endl;
    return 0;
    }
    std::cout << "The size of the vector will be random between 1 - " << N << " ." << std::endl;

    struct timeval start, end;
    Vector<int> b[TIMES];
    int size[TIMES];
    int val[TESTNUM], space[TESTNUM];

    /// Get the random number of sizes.
    for (int i = 0; i < TIMES; i++)
    size[i] = rand() % 10000 * 1000 + rand() % 1000 +1;

    /// Get the different number of SPARE_CAPACITY.
    for (int i = 0; i < TESTNUM - 3; i++)
        space[i] = pow( 2, i );
    space[TESTNUM - 3] = 5000000;
    space[TESTNUM - 2] = 10000000;
    space[TESTNUM - 1] = 15000000;

    /// Use circulation to calculate the time interval for each SPARE_CAPACITY.
    for (int l = 0; l < TESTNUM; l++)
    {
        gettimeofday( &start, NULL);
        for (int k = 0; k < TIMES; k++)
        {
            b[k].clearVector();
            b[k].reserve( space[l] );
            if( k == 0)
                std::cout << b[k].capacity() << std::endl;

            for (int i = 0; i < size[k]; i++)
            {
                b[k].push_back(a[i]);
            }
           
            if (b[k].empty())
            {
                std::cout << "Unable to copy the vector." << std::endl;
                return 0;
            }     
        }
        gettimeofday( &end, NULL);
        val[l] = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000;

        std::cout << "The total time with SPARR_CAPACITY = " << space[l] << " is " << val[l] << "ms" << std::endl;
    }

    /// To get the most effecient one.
    int min = minimal( val, TESTNUM);
    std::cout << "The SPARE_CAPACITY that has used the least time totally is " << space[min] << std::endl;
    std::cout << "The time is " << val[min] << "ms" << std::endl;

    return 0;
}
